﻿using System;
using System.Collections.Generic;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Quartz;
using Senparc.Weixin;
using Senparc.Weixin.Exceptions;
using Senparc.Weixin.MP.CommonAPIs;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.QuartzJobs
{
    public class SendBookRemindNoticeJob:IJob
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(SendBookRemindNoticeJob)); 
        const string TopColor = "#0000FF";

        const string FirstColor = "#173177";

        const string RemarkColor = "#173177";

        const string NoticeColor = "#173177";

        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("[{0}] 获取消息推送", DateTime.Now.ToString("MM-dd HH:mm:ss"));
            List<ApptAttnLog> attnLogs;
            using (var ctx = new FsssdqfybjyEntities())
            {
                var now = DateTime.Now.ToString("yyyy-MM-dd");
                var day1 = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");
                attnLogs =
                    ctx.ApptAttnLogs.Where(
                        x => (x.SendTimes.Value < 1 && SqlFunctions.DateDiff("SECOND", x.NeedToSendTime1, SqlFunctions.GetDate()) > 0 && x.RegDate == day1)
                            || (x.SendTimes.Value < 2 && SqlFunctions.DateDiff("SECOND", x.NeedToSendTime2, SqlFunctions.GetDate()) > 0 && x.RegDate == now)).Take(10).ToList();
                Console.WriteLine("[{0}] 获取消息推送：{1}", DateTime.Now.ToString("MM-dd HH:mm:ss"), attnLogs.Count.ToStringOrDefault());
            }
            foreach (var log in attnLogs)
            {
                SendAttnNotice(log.Id);
            }
            Console.WriteLine("[{0}] 完成消息推送", DateTime.Now.ToString("MM-dd HH:mm:ss"));
        }
        
        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="logId"></param>
        private void SendAttnNotice(long logId)
        {
           
            ApptAttnLog attnLog;
            WxUser wxUser;
            BookOrder order;

            var needSend = false; //发送标识
            using (var ctx = new FsssdqfybjyEntities())
            {
                attnLog = ctx.ApptAttnLogs.FirstOrDefault(x => x.Id == logId);
                if (attnLog == null)
                {
                    attnLog.SendTimes = 3;
                    attnLog.RecUpdateDt = DateTime.Now;
                    ctx.SaveChanges();
                    return;
                }
                

                order = ctx.BookOrders.FirstOrDefault(x => x.Id == attnLog.OrderId.Value);
                if (order == null)
                {
                    attnLog.SendTimes = 4;
                    attnLog.RecUpdateDt = DateTime.Now;
                    ctx.SaveChanges();
                    return;
                }

                wxUser = ctx.WxUsers.FirstOrDefault(x => x.Id == attnLog.WxUserId);
                if (wxUser == null)
                {
                    attnLog.SendTimes = 5;
                    attnLog.RecUpdateDt = DateTime.Now;
                    ctx.SaveChanges();
                    return;
                }

                var card =
                    ctx.HospCards.FirstOrDefault(
                        x => x.CardNo == attnLog.CardNo && x.RecStatus == 1 && x.WxUserId == attnLog.WxUserId);
                if (card == null)
                {
                    attnLog.SendTimes = 6;
                    attnLog.RecUpdateDt = DateTime.Now;
                    ctx.SaveChanges();
                    return;
                }

                attnLog.SendTimes = attnLog.SendTimes ?? 0;

                //order.CardNo 
                //attnLog.CardNo
                var state = GetOrderStatusFromHis(order.CardNo, order.FlowNo);

                if (order.BookStatus != 1 || state != "未生效") //未预约成功，或订单已经失效
                {
                    attnLog.SendTimes = 2;
                    attnLog.RecUpdateDt = DateTime.Now;
                }
                else
                {
                    if (string.IsNullOrEmpty(attnLog.PatientName))
                    {
                        var hospCard = ctx.HospCards.FirstOrDefault(x => x.CardNo == attnLog.CardNo);
                        attnLog.PatientName = hospCard.PatientName;
                    }
                    if (attnLog.SendTimes == 0)
                    {
                        if (DateTime.Now.Date > DateTime.Parse(attnLog.RegDate))
                        {
                            attnLog.SendTimes = 2;
                            attnLog.RecUpdateDt = DateTime.Now;
                        }
                        else if (DateTime.Now.Date == DateTime.Parse(attnLog.RegDate))
                        {
                            attnLog.SendTimes = 1;
                            attnLog.RecUpdateDt = DateTime.Now;
                        }
                        else
                        {
                            if (DateTime.Now > attnLog.NeedToSendTime1)
                            {
                                attnLog.SendTimes++;
                                attnLog.SendTime1 = DateTime.Now;
                                attnLog.RecUpdateDt = DateTime.Now;
                                needSend = true;
                            }
                        }
                    }
                    else
                    {
                        if (DateTime.Now.Date > DateTime.Parse(attnLog.RegDate))
                        {
                            attnLog.SendTimes = 2;
                            attnLog.RecUpdateDt = DateTime.Now;
                        }
                        else
                        {
                            if (DateTime.Now > attnLog.NeedToSendTime2)
                            {
                                if (DateTime.Now > DateTime.Parse(order.BookStartTime))
                                {
                                    attnLog.SendTimes = 2;
                                    attnLog.RecUpdateDt = DateTime.Now;
                                }
                                else
                                {
                                    attnLog.SendTimes++;
                                    attnLog.SendTime2 = DateTime.Now;
                                    attnLog.RecUpdateDt = DateTime.Now;
                                    needSend = true;
                                }
                            }
                        }
                    }
                }
                ctx.SaveChanges();
            }

            if (!needSend)
                return;

            Console.WriteLine("正在发送就诊提醒，预约订单ID：{0}", order.Id);

            #region 发送模板消息

            var openId = wxUser.OpenId;
            var templateId = "Pbrc7UUcLdtmwwtBlgQCcBjAAQjfoMYBfwCxBuqP1i0";
            var url = MessageHelper.GetH5Url("/index/get-queue");
            var strremark = $"温馨提醒：您预约的时间已经临近（就诊人：{order.CardName}）";
            var data = new
            {
                first = new
                {
                    value = strremark,
                    color = FirstColor
                },
                keyword1 = new
                {
                    value = order.CardName, //就诊人
                    color = NoticeColor
                },
                keyword2 = new
                {
                    value = order.CardNo, //卡号
                    color = NoticeColor
                },
                keyword3 = new
                {
                    value = attnLog.HospName, //就诊医院
                    color = NoticeColor
                },
                keyword4 = new
                {
                    value = attnLog.DeptName, //就诊科室
                    color = NoticeColor
                },
                keyword5 = new
                {
                    value = attnLog.RegDate + " " + attnLog.TimeSlice, //就诊时间
                    color = NoticeColor
                },
                remark = new
                {
                    value = "请您带齐相关资料，于就诊前到15分钟到达我院候诊，谢谢合作",
                    color = RemarkColor
                }
            };
            try
            {
                MessageHelper.SendTemplateMessage("预约就诊提醒通知", strremark, null, openId, templateId, TopColor,
                    url, data);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("发送预约就诊提醒消息时出错，信息：{0}", JsonConvert.SerializeObject(ex));
            }
            #endregion
        }

        /// <summary>
        /// 查询HIS系统中，预约订单状态
        /// </summary>
        /// <param name="cardNo">卡号</param>
        /// <param name="flowNo">预约流水号</param>
        /// <returns>返回状态: 未生效/已报到/作废/过期</returns>
        private string GetOrderStatusFromHis(string cardNo, string flowNo)
        {
            string retStr = "";

            var startDate = DateTime.Now.ToString("yyyy-MM-dd");
            var endDate = DateTime.Now.AddMonths(1).ToString("yyyy-MM-dd");

            var request = new Request4GetBookInfo();
            request.HosPatId = "";
            request.ClinNo = "";
            request.IdCard = "";
            request.CardNo = cardNo;
            request.FlowNo = "";
            request.StartDate = startDate;
            request.EndDate = endDate;

            Response4GetBookInfo response4GetGetBookInfo;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisWs/GetBookInfo", request).Result;
                responseMsg.EnsureSuccessStatusCode();
                response4GetGetBookInfo = responseMsg.Content.ReadAsAsync<Response4GetBookInfo>().Result;
            }
            catch (Exception)
            {
                return retStr;
            }

            //获取院内webservice信息时出现错误 (院内webservice层错误)
            if (response4GetGetBookInfo.ResultCode != "0")
            {
                return retStr;
            }

            if (response4GetGetBookInfo.BookInfoList.Count == 0)
            {
                retStr = "过期";
                return retStr;
            }

            foreach (var bookInfo in response4GetGetBookInfo.BookInfoList)
            {
                if (bookInfo.FlowNo == flowNo)
                {
                    retStr = bookInfo.State.Trim();
                }
            }
            return retStr;
        }
    }
}
